Imports System.Collections.Generic
Imports System.IO
Imports System.Text
Imports System.Windows.Forms
Imports DemosCommonCode.Imaging
Imports Vintasoft.Imaging
Imports Vintasoft.Pdf
Imports Vintasoft.Pdf.Tree
Imports DemosCommonCode.Imaging.Codecs

Namespace Pdf
	Public Partial Class ResourcesViewerForm
		Inherits Form

		#Region "Fields"

		Private _resources As New Dictionary(Of String, PdfResource)()
		Private _textDataEncoding As Encoding = Encoding.ASCII
		Private _focusedImage As VintasoftImage
		Private _focusedPage As PdfPage
		Private _names As IList(Of String) = Nothing

		#End Region



		#Region "Constructors"

		Private Sub New()
			InitializeComponent()
			imageViewer.Visible = InlineAssignHelper(textDataPanel.Visible, False)
			imageViewer.Dock = InlineAssignHelper(textDataPanel.Dock, DockStyle.Fill)

			CodecsFileFilters.SetFilters(saveImageDialog, False)
		End Sub

		Public Sub New(document As PdfDocument)
			Me.New()
			Try
				AddImages(document.Images)
				If resourceSelector.Items.Count > 0 Then
					resourceSelector.SelectedIndex = 0
				End If
			Catch ex As Exception
				DemosTools.ShowErrorMessage(ex)
			End Try
		End Sub

		Public Sub New(imageResource As PdfImageResource, focusedImage As VintasoftImage, focusedPage As PdfPage)
			Me.New()
			_focusedImage = focusedImage
			_focusedPage = focusedPage
			AddResource(imageResource.ObjectNumber.ToString(), imageResource)
			resourceSelector.SelectedIndex = 0
		End Sub

		Public Sub New(imageResources As IList(Of PdfImageResource), focusedImage As VintasoftImage, focusedPage As PdfPage, names As IList(Of String))
			Me.New()
			_focusedImage = focusedImage
			_focusedPage = focusedPage
			_names = names
			AddImages(imageResources)
			If resourceSelector.Items.Count > 0 Then
				resourceSelector.SelectedIndex = 0
			End If
		End Sub

		Public Sub New(imageResources As IList(Of PdfImageResource))
			Me.New(imageResources, Nothing)
		End Sub

		Public Sub New(imageResources As IList(Of PdfImageResource), names As IList(Of String))
			Me.New(imageResources, Nothing, Nothing, names)
		End Sub

		Public Sub New(page As PdfPage)
			Me.New()
			AddImages(page.Images)
			If resourceSelector.Items.Count > 0 Then
				resourceSelector.SelectedIndex = 0
			End If
		End Sub

		'public ResourcesViewerDialog(PdfResource[] resources)
		'    : this()
		'{
		'    for (int i = 0; i < resources.Length; i++)
		'    {
		'        string name = resources[i].ObjectNumber.ToString();
		'        _resources.Add(name, resources[i]);
		'        resourceSelector.Items.Add(name);
		'    }
		'    if (resourceSelector.Items.Count > 0)
		'        resourceSelector.SelectedIndex = 0;
		'}

		#End Region



		#Region "Properties"

		Public ReadOnly Property SelectedResource() As PdfResource
			Get
				If resourceSelector.SelectedIndex >= 0 Then
					Return _resources(DirectCast(resourceSelector.SelectedItem, String))
				End If
				Return Nothing
			End Get
		End Property

		#End Region



		#Region "Methods"

		Protected Overrides Sub OnShown(e As EventArgs)
			MyBase.OnShown(e)
			resourceSelector.Focus()
		End Sub

		Private Sub AddImages(images As IList(Of PdfImageResource))
			For i As Integer = 0 To images.Count - 1
				Dim name As String = images(i).ObjectNumber.ToString()
				If _names IsNot Nothing Then
					name = String.Format("{0}: {1}", name, _names(i))
				End If
				AddResource(name, images(i))
			Next
		End Sub

		Private Sub AddResource(name As String, streamObject As PdfResource)
			_resources.Add(name, streamObject)
			resourceSelector.Items.Add(name)
		End Sub

		Private Sub ShowImageData(image As VintasoftImage)
			Dim img As VintasoftImage = imageViewer.Image
			imageViewer.Image = image
			If img IsNot Nothing Then
				img.Dispose()
			End If
			imageViewer.Visible = True
			textDataPanel.Visible = False
			saveResourceAsImage.Enabled = True
		End Sub

		Private Sub ShowBinaryData(data As Byte())
			Dim sb As New StringBuilder()
			Dim line As Integer = 16
			For i As Integer = 0 To data.Length - 1
				If i Mod line = 0 Then
					If i <> 0 Then
						For j As Integer = i - line To i - 1
							Dim val As Byte = data(j)

							If val >= 32 AndAlso val <= 127 Then
								sb.Append(ChrW(val))
							Else
								sb.Append("?"C)
							End If
						Next
						sb.AppendLine()
					End If
					sb.Append(String.Format("0x{0} ", i.ToString("X8")))
				End If
				If (i Mod line <> 0) AndAlso (i Mod (line \ 2) = 0) Then
					sb.Append("| ")
				End If
				sb.Append(String.Format("{0} ", data(i).ToString("X2")))
			Next
			textData.[ReadOnly] = True
			textData.WordWrap = False
			ShowTextDataInternal(sb.ToString())
		End Sub

		Private Sub ShowTextDataInternal(data As String)
			saveResourceAsImage.Enabled = False
			textData.Text = data
			textDataPanel.Visible = True
			imageViewer.Visible = False
		End Sub
		Private Sub ShowTextData(data As String)
			If data.Contains(vbLf) Then
				data = data.Replace(vbLf, Environment.NewLine)
			Else
				data = data.Replace(vbCr, Environment.NewLine)
			End If
			textData.[ReadOnly] = False
			textData.WordWrap = True
			ShowTextDataInternal(data)
		End Sub

		Private Sub DrawSelectedStreamObject()
			Dim resourceStream As PdfResource = SelectedResource
			If TypeOf resourceStream Is PdfImageResource Then
				ShowImageData(DirectCast(resourceStream, PdfImageResource).GetImage())
			Else
				ShowTextData(_textDataEncoding.GetString(resourceStream.GetBytes()))
			End If
		End Sub

		Private Sub resourceSelector_SelectedIndexChanged(sender As Object, e As EventArgs)
			propertyGrid.SelectedObject = SelectedResource
			DrawSelectedStreamObject()
		End Sub

		Private Sub button1_Click(sender As Object, e As EventArgs)
			If imageViewer.Image IsNot Nothing Then
				SaveImageFileForm.SaveImageToFile(imageViewer.Image)
			End If
		End Sub

		Private Sub button2_Click(sender As Object, e As EventArgs)
			Dim dlg As New PropertyGridForm(PdfCompressionSettings.DefaultSettings, "Compression Default Params")
			dlg.ShowDialog()
		End Sub

		Private Sub propertyGrid_PropertyValueChanged(s As Object, e As PropertyValueChangedEventArgs)
			DrawSelectedStreamObject()
			If _focusedPage IsNot Nothing AndAlso _focusedImage IsNot Nothing Then
				Dim resourceStream As PdfResource = SelectedResource
				If resourceStream IsNot Nothing Then
					If TypeOf resourceStream Is PdfImageResource Then
						If _focusedPage.Images.IndexOf(DirectCast(resourceStream, PdfImageResource)) >= 0 Then
							_focusedImage.Reload(True)
						End If
					End If
				End If
			End If
		End Sub

		Private Sub saveResourceAsBinary_Click(sender As Object, e As EventArgs)
			If SelectedResource IsNot Nothing AndAlso saveBinaryDataDialog.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
				File.WriteAllBytes(saveBinaryDataDialog.FileName, SelectedResource.GetBytes())
			End If
		End Sub


		Private Sub renderingForm_CheckedChanged(sender As Object, e As EventArgs)
			DrawSelectedStreamObject()
		End Sub

		Private Sub buttonOk_Click(sender As Object, e As EventArgs)
			DialogResult = DialogResult.OK
		End Sub

		Private Sub buttonCancel_Click(sender As Object, e As EventArgs)
			DialogResult = DialogResult.Cancel
		End Sub
		Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
			target = value
			Return value
		End Function

		#End Region

	End Class
End Namespace
